package com.boss.asset.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.boss.api.dto.ApiResultDTO;
import com.boss.asset.dao.IAssetExtDao;
import com.boss.asset.dao.IAssetInfoDao;
import com.boss.asset.dao.IAssetInfoFlowDao;
import com.boss.asset.dao.ITodoDao;
import com.boss.asset.entity.BasAssetBiz;
import com.boss.asset.entity.BasAssetExt;
import com.boss.asset.entity.BasAssetInfo;
import com.boss.asset.service.IAssetInfoService;
import com.boss.common.entity.WfActionDTO;
import com.boss.common.enums.ActionTypeEnum;
import com.boss.common.service.IWorkflowBusiness;
import com.boss.framework.exception.AppRuntimeException;
import com.boss.sys.ca.role.dto.RoleDTO;
import com.boss.sys.ca.user.dto.UserDTO;
import com.boss.sys.config.CseCommonConfiguration;
import com.boss.sys.utils.SysUtils;
import com.boss.sys.workflow.dto.TaskDTO;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.StringUtils;
import org.springframework.web.client.RestTemplate;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Service
public class AssetInfoServiceImpl implements IAssetInfoService {

    /**
     * 引入日志框架常量
     */
    private final static Logger logger = LoggerFactory.getLogger(AssetInfoServiceImpl.class);

    @Autowired
    private IAssetInfoFlowDao assetInfoFlowDao;
    @Autowired
    private IAssetInfoDao assetInfoDao;
    @Autowired
    private IAssetExtDao assetExtDao;
    /**
     * 工作流实现类
     */
    @Autowired
    private IWorkflowBusiness workflowBusiness;
    @Autowired
    private ITodoDao homePageTodoDao;

    /**
     * 引入接口服务配置类
     */
    @Autowired
    private CseCommonConfiguration urlConfiguration;

    @Autowired
    private RestTemplate restTemplate;

    /**
     * 常量：流程名称
     */
    private final static String PRO_DEF_KEY = "bas_asset_manager";

    private static final String RS_100000 = "100000";







    @Override
    @Transactional(rollbackFor = Exception.class)
    public void passAssetInfo(UserDTO userDTO, WfActionDTO wfAction) throws AppRuntimeException {
        List<String> idList = (List<String>) wfAction.getBizDatas();
        //回写主表数据
        writeBackAssetInfo(idList);
        ApiResultDTO apiResultDTO = getWorkFlowResult(userDTO, idList, "审核通过",
                wfAction.getMenuguid(), ActionTypeEnum.WF_AUDIT, wfAction.getMessage());
        if (!RS_100000.equals(apiResultDTO.getRscode())) {
            throw new AppRuntimeException(apiResultDTO.getResult());
        }
    }





    /**
     * 调用工作流并获取返回值
     *
     * @param userDTO
     * @param idList
     * @param actionName
     * @param menuguid
     * @param wfAudit
     * @return
     * @throws AppRuntimeException
     */
    private ApiResultDTO getWorkFlowResult(UserDTO userDTO, List<String> idList, String actionName, String menuguid,
                                           ActionTypeEnum wfAudit, String actionMessage) throws AppRuntimeException {
//        return this.workflowBusiness.doWorkFlow(userDTO, actionName, PRO_DEF_KEY,
//                "id", idList, menuguid, wfAudit, actionMessage);
        return null;
    }

    /**
     * 根据资产流程信息id 将流程数据 回写到正式表中
     *
     * @param idList
     */
    private void writeBackAssetInfo(List<String> idList) {
        //将资产流程数据 转移到正式表中
        for (int i = 0; i < idList.size(); i++) {
            String id = idList.get(i);
            BasAssetBiz basAssetBiz = assetInfoFlowDao.getAssetFlowById(id);
            BasAssetInfo basAssetInfo = new BasAssetInfo();
            BasAssetExt basAssetExt = new BasAssetExt();
            BeanUtils.copyProperties(basAssetBiz, basAssetInfo);
            BeanUtils.copyProperties(basAssetBiz, basAssetExt);
            assetInfoDao.insert(basAssetInfo);
            assetExtDao.insert(basAssetExt);
        }
    }






    @Override
    public List<Map<String, Object>>  queryAssetInfo(String agencyCode, String province, String year) {
        return assetInfoDao.getAssetInfo(agencyCode, province, year);
    }

    @Override
    public Map<String,String> getBaseData(String elementCode, String province) {
        String json = restTemplate.getForObject(urlConfiguration.getBasedataservice()+"/v2/basedata/{elementcode}/{province}",String.class,elementCode,province);
        Map<String,String> resultMap = new HashMap<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            if(jsonArray != null){
                for(int i=0;i<jsonArray.size();i++) {
                    JSONObject obj = jsonArray.getJSONObject(i);
                    resultMap.put(obj.getString("code"),obj.getString("name"));
                }
            }
        }
        return resultMap;
    }

    @Override
    public List<Map<String, String>> getBaseDataSelect(String elementCode, String province) {
        String json = restTemplate.getForObject(urlConfiguration.getBasedataservice()+"/v2/basedata/{elementcode}/{province}",String.class,elementCode,province);
        List<Map<String, String>> resultList = new ArrayList<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            if(jsonArray != null){
                for(int i=0;i<jsonArray.size();i++) {
                    JSONObject obj = jsonArray.getJSONObject(i);
//                    if ("1".equals(obj.getString("isleaf"))) {
                        Map<String,String> resultMap = new HashMap<>();
                        resultMap.put("code", obj.getString("code"));
                        resultMap.put("name", obj.getString("name"));
                        resultList.add(resultMap);
//                    }
                }
            }
        }
        return resultList;
    }

    @Override
    public List<Map<String, Object>> getPayCategoryTree(String elementCode, String province) {
        String json = restTemplate.getForObject(urlConfiguration.getBasedataservice()+"/v2/basedata/{elementcode}/{province}",String.class,elementCode,province);
        List<Map<String, Object>> resultList = new ArrayList<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))) {
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            resultList = payCategoryTree(jsonArray, "0");
        }
        return resultList;
    }

    @Override
    public List<Map<String, Object>> getBaseDataDepBgtEcoTree(String elementCode, String province) {
        String json = restTemplate.getForObject(urlConfiguration.getBasedataservice()+"/v2/basedata/{elementcode}/{province}",String.class,elementCode,province);
        List<Map<String, Object>> resultList = new ArrayList<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))) {
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            resultList = tree(jsonArray, "0");
        }
        return resultList;
    }

    @Override
    public List<Map<String, Object>> getBaseDataGovBgtEcoTree(String elementCode, String province) {
        String json = restTemplate.getForObject(urlConfiguration.getBasedataservice()+"/v2/basedata/{elementcode}/{province}",String.class,elementCode,province);
        List<Map<String, Object>> resultList = new ArrayList<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))) {
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            resultList = tree(jsonArray, "0");
        }
        return resultList;
    }

    @Override
    public List<Map<String, Object>> getBaseDataFuncTree(String elementCode, String province) {
        String json = restTemplate.getForObject(urlConfiguration.getBasedataservice()+"/v2/basedata/{elementcode}/{province}",String.class,elementCode,province);
        List<Map<String, Object>> resultList = new ArrayList<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))) {
            JSONArray jsonArray = jsonObject.getJSONArray("data");
            resultList = treeAll(jsonArray, "0");
        }
        return resultList;
    }

    /**
     * 获取所有数据树结构数据
     * @param jsonArray 工资列表数据
     * @param guid 父id
     *             只获取code是11的数据
     * @return
     */
    private List<Map<String, Object>> payCategoryTree(JSONArray jsonArray, String guid) {
        List<Map<String, Object>> resultTree = new ArrayList<>();
        if (jsonArray != null && jsonArray.size() > 0) {
            for (int i = 0; i < jsonArray.size() ; i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                // 顶级
                if ("1" .equals(jsonObject.getString("levelno")) && "0".equals(guid)) {
                    if ("1".equals(jsonObject.getString("code")) &&
                            "804a28af1d0c11eb8728fa163e8b0246".equals(jsonObject.getString("dicdsguid"))) {
                        List<Map<String, Object>> childrenList = null;
                        Map<String, Object> map = new HashMap<>();
                        map.put("label", jsonObject.getString("code") + "-" + jsonObject.getString("name"));
                        map.put("code", jsonObject.getString("code"));
                        String parGuid = jsonObject.getString("id");
                        map.put("id", parGuid);
                        String leaf = String.valueOf(jsonObject.getString("isleaf"));
                        map.put("isleaf", leaf);
                        if (!"1".equals(leaf)) {
                            childrenList = payCategoryTree(jsonArray, parGuid);
                            map.put("children", childrenList);
                        }
                        if ("1".equals(leaf)) {
                            resultTree.add(map);
                        } else if (!StringUtils.isEmpty(childrenList) && childrenList.size() > 0) {
                            resultTree.add(map);
                        }
                    }
                } else  {
                    String superguid = jsonObject.getString("superguid");
                    if (guid.equals(superguid)) {
//                        if ("11".equals(jsonObject.getString("code"))) {
                            List<Map<String, Object>> childrenList = null;
                            Map<String, Object> map = new HashMap<>();
                            map.put("label", jsonObject.getString("code") + "-" + jsonObject.getString("name"));
                            map.put("code", jsonObject.getString("code"));
                            String parGuid = jsonObject.getString("id");
                            map.put("id", parGuid);
                            String leaf = String.valueOf(jsonObject.getString("isleaf"));
                            map.put("isleaf", "1");
                            /*if ("0".equals(leaf)) {
                                childrenList = payCategoryTree(jsonArray, parGuid);
                                map.put("children", childrenList);
                            }*/
                            resultTree.add(map);
                            /*if (!"0".equals(leaf)) {
                            } else if (!StringUtils.isEmpty(childrenList) && childrenList.size() > 0) {
                                resultTree.add(map);
                            }*/
//                        }
                    }
                }
            }
        }
        return resultTree;
    }


    /**
     * 获取所有数据树结构数据
     * @param jsonArray 政府经济分类数据
     * @param guid 父id
     * @return
     */
    private List<Map<String, Object>> tree(JSONArray jsonArray, String guid) {
        List<Map<String, Object>> resultTree = new ArrayList<>();
        if (jsonArray != null && jsonArray.size() > 0) {
            for (int i = 0; i < jsonArray.size() ; i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                // 顶级
                if ("1" .equals(jsonObject.getString("levelno")) && "0".equals(guid)) {
                    List<Map<String, Object>> childrenList = null;
                    Map<String, Object> map = new HashMap<>();
                    map.put("label", jsonObject.getString("code") + "-" + jsonObject.getString("name"));
                    map.put("code", jsonObject.getString("code"));
                    String parGuid = jsonObject.getString("id");
                    map.put("id", parGuid);
                    String leaf = String.valueOf(jsonObject.getString("isleaf"));
                    map.put("isleaf", leaf);
                    if (!"1".equals(leaf)) {
                        childrenList = tree(jsonArray, parGuid);
                        map.put("children", childrenList);
                    }
                    if ("1".equals(leaf)) {
                        resultTree.add(map);
                    } else if (!StringUtils.isEmpty(childrenList) && childrenList.size() > 0) {
                        resultTree.add(map);
                    }
                } else  {
                    String superguid = jsonObject.getString("superguid");
                    if (guid.equals(superguid)) {
                        List<Map<String, Object>> childrenList = null;
                        Map<String, Object> map = new HashMap<>();
                        map.put("label", jsonObject.getString("code") + "-" + jsonObject.getString("name"));
                        map.put("code", jsonObject.getString("code"));
                        String parGuid = jsonObject.getString("id");
                        map.put("id", parGuid);
                       // String leaf = String.valueOf(jsonObject.getString("isleaf"));//经济分类只要到第二层，若以后还要其他层可将该行解开
                        String leaf ="1";
                        map.put("isleaf", leaf);
                        if (!"1".equals(leaf)) {
                            childrenList = tree(jsonArray, parGuid);
                            map.put("children", childrenList);
                        }
                        if ("1".equals(leaf)) {
                            resultTree.add(map);
                        } else if (!StringUtils.isEmpty(childrenList) && childrenList.size() > 0) {
                            resultTree.add(map);
                        }
                    }
                }
            }
        }
        return resultTree;
    }

    /**
     * 获取所有数据树结构数据
     * @param jsonArray 政府经济分类数据
     * @param guid 父id
     * @return
     */
    private List<Map<String, Object>> treeAll(JSONArray jsonArray, String guid) {
        List<Map<String, Object>> resultTree = new ArrayList<>();
        if (jsonArray != null && jsonArray.size() > 0) {
            for (int i = 0; i < jsonArray.size() ; i++) {
                JSONObject jsonObject = jsonArray.getJSONObject(i);
                // 顶级
                if ("1" .equals(jsonObject.getString("levelno")) && "0".equals(guid)) {
                    List<Map<String, Object>> childrenList = null;
                    Map<String, Object> map = new HashMap<>();
                    map.put("label", jsonObject.getString("code") + "-" + jsonObject.getString("name"));
                    map.put("code", jsonObject.getString("code"));
                    String parGuid = jsonObject.getString("id");
                    map.put("id", parGuid);
                    String leaf = String.valueOf(jsonObject.getString("isleaf"));
                    map.put("isleaf", leaf);
                    if (!"1".equals(leaf)) {
                        childrenList = treeAll(jsonArray, parGuid);
                        map.put("children", childrenList);
                    }
                    if ("1".equals(leaf)) {
                        resultTree.add(map);
                    } else if (!StringUtils.isEmpty(childrenList) && childrenList.size() > 0) {
                        resultTree.add(map);
                    }
                } else  {
                    String superguid = jsonObject.getString("superguid");
                    if (guid.equals(superguid)) {
                        List<Map<String, Object>> childrenList = null;
                        Map<String, Object> map = new HashMap<>();
                        map.put("label", jsonObject.getString("code") + "-" + jsonObject.getString("name"));
                        map.put("code", jsonObject.getString("code"));
                        String parGuid = jsonObject.getString("id");
                        map.put("id", parGuid);
                        String leaf = String.valueOf(jsonObject.getString("isleaf"));//经济分类只要到第二层，若以后还要其他层可将该行解开

                        map.put("isleaf", leaf);
                        if (!"1".equals(leaf)) {
                            childrenList = treeAll(jsonArray, parGuid);
                            map.put("children", childrenList);
                        }
                        if ("1".equals(leaf)) {
                            resultTree.add(map);
                        } else if (!StringUtils.isEmpty(childrenList) && childrenList.size() > 0) {
                            resultTree.add(map);
                        }
                    }
                }
            }
        }
        return resultTree;
    }


    @Override
    public JSONArray getBaseDataInfo(String elementCode, String province) {
        String json = restTemplate.getForObject(urlConfiguration.getBasedataservice()+"/v2/basedata/{elementcode}/{province}",String.class,elementCode,province);
        JSONArray jsonArray = null;
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            jsonArray = jsonObject.getJSONArray("data");
        }
        return jsonArray;
    }

    @Override
    public List<Map<String, String>> getProDataSelect(UserDTO userDTO) {
        Map<String, Object> requestMap = new HashMap<>(3);
        requestMap.put("agencycode", userDTO.get("orgcode"));
        requestMap.put("year", userDTO.getYear());
        requestMap.put("province", userDTO.getProvince());
        String url = urlConfiguration.getBasedataservice()+"/v2/basedata/project?year="+ userDTO.getYear() + "&province=" + userDTO.getProvince();
        List<Map<String, String>> resultList = new ArrayList<>();
        try {
            String json = restTemplate.getForObject(url, String.class);
            logger.info("=======getProDataSelect back:" + json);
            JSONObject jsonObject = JSON.parseObject(json);

            if (!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))) {
                JSONArray jsonArray = jsonObject.getJSONArray("data");
                if (jsonArray != null) {
                    for (int i = 0; i < jsonArray.size(); i++) {
                        JSONObject obj = jsonArray.getJSONObject(i);
                        Map<String, String> resultMap = new HashMap<>();
                        resultMap.put("code", obj.getString("code"));
                        resultMap.put("name", obj.getString("code")+"-"+obj.getString("name"));
                        resultList.add(resultMap);
                    }
                }
            }
        }catch (Exception e){
            logger.info("====getProDataSelect error:"+e.getMessage());
        }
        return resultList;
    }

    @Override
    public JSONArray getBaseDataTree(String elementCode, String province) {
        JSONArray jsonArray = null;
        String json = restTemplate.getForObject(urlConfiguration.getBasedataservice()+"/v2/basedata/{elementcode}/{province}",String.class,elementCode,province);
        List<Map<String, String>> resultList = new ArrayList<>();
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            jsonArray = jsonObject.getJSONArray("data");
        }
        return jsonArray;
    }

    @Override
    public JSONArray getAuthAgency(UserDTO userDTO, String elemtntCode) {
        RoleDTO role=getRole(userDTO);
        JSONArray jsonArray = null;
        Map<String, Object> requestMap = new HashMap<>(4);
        requestMap.put("userguid", userDTO.getGuid());
        requestMap.put("roleguid", role.getGuid());
        requestMap.put("year", userDTO.getYear());
        requestMap.put("province", userDTO.getProvince());
//        String adminjson = restTemplate.getForObject(urlConfiguration.getPermservice()+"/v2/right/elementright?userguid={userguid}&elementcode={elementcode}&year={year}&province={province}",
//                String.class, requestMap);//原获取单位权限方法，缺少财政用户配置单位权限接口
        String json = restTemplate.getForObject(urlConfiguration.getPermservice()+"/v2/right/dataright?userguid={userguid}&roleguid={roleguid}&year={year}&province={province}",
                String.class, requestMap);
        JSONObject jsonObject = JSON.parseObject(json);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))) {
                if (!jsonObject.getJSONObject("data").isEmpty()) {
                    if (jsonObject.getJSONObject("data").getJSONObject("orgs") != null) {
                        jsonArray = jsonObject.getJSONObject("data").getJSONObject("orgs").getJSONArray("agency");//未单独设置机构权限用户
                    } else if (jsonObject.getJSONObject("data").getJSONObject("element") != null) {
                        jsonArray = jsonObject.getJSONObject("data").getJSONObject("element").getJSONArray("agency");//财政用户单独设置机构权限
                    }
                }
            }
        return jsonArray;
    }

    /**
     *  查询工作流代办信息
     * @param config
     * @param userguid
     * @param roleguid
     * @param menuguid
     * @param province
     * @param year
     * @return
     * @throws AppRuntimeException
     */
    @Override
    public List<Map<String, Object>> getFlowTaskData(Map<String, Object> config, String userguid,String roleguid,String menuguid,String province, String year) throws AppRuntimeException {
        long starttime = System.currentTimeMillis();
        //调用工作流查询代办，返回业务数据id
        List<TaskDTO> tasks=workflowBusiness.getToDoTask(config,menuguid,province,year);
        //获取业务数据ids
        List<Map<String,Object>> statusNums = (List<Map<String, Object>>) tasks.get(0).get("statusNums");
        List<Map<String, Object>> taskInfoList=null;
        for (Map<String, Object> statusNum : statusNums) {
            if(statusNum.get("status").equals("1")){ //待办
                List<String> bizkeys = (List<String>) statusNums.get(0).get("bizkeys");
                taskInfoList = homePageTodoDao.getFlowTaskData(bizkeys,config,userguid,
                        roleguid, menuguid,province, year);
                logger.info("查询业务系统代办数据耗时: {}ms", System.currentTimeMillis() - starttime);
            }
        }

        return taskInfoList;
    }

    public RoleDTO getRole(UserDTO userDTO){
        RoleDTO roleDTO=new RoleDTO();
        JSONArray jsonArray = null;
        String roleJsonStr = restTemplate.getForObject(urlConfiguration.getPermservice()+"/v2/userroles?userguid={userguid}&year={year}&province={province}", String.class, userDTO.getGuid(),userDTO.getYear(),userDTO.getProvince());
        JSONObject jsonObject = JSON.parseObject(roleJsonStr);
        if(!SysUtils.isNullOrEmpty(jsonObject) && "100000".equals(jsonObject.getString("rscode"))){
            jsonArray=jsonObject.getJSONArray("data");
            if(jsonArray!=null){
                for(int i = 0; i < jsonArray.size(); i++){
                    JSONObject roleJosn = jsonArray.getJSONObject(i);
                    if("salary".equals(roleJosn.getString("appid"))){
                        roleDTO.setGuid(roleJosn.getString("guid"));
                    }
                }

            }
        }

        return roleDTO;
    }
}
